package com.trade.module.base.service.impl;

import com.trade.module.base.entity.Dictionary;
import com.trade.module.base.entity.User;
import com.trade.module.base.repository.DictionaryRepository;
import com.trade.module.base.repository.UserRepository;
import com.trade.module.base.service.DictionaryService;
import com.trade.system.sysrun.DictionaryUtil;
import com.trade.common.utils.*;
import com.trade.module.base.vo.DictionaryVo;
import lombok.extern.log4j.Log4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.*;

/**
 * Class Description: 数据字典服务层
 *
 * @Version v1.0 2017/4/22 22:58
 * @JDK version 1.8.0_51
 * @Author zfb
 */
@Log4j
@Service
@Transactional
public class DictionaryServiceImpl implements DictionaryService {

    @Autowired
    private DictionaryRepository dictionaryRepository;
    @Autowired
    private UserRepository userRepository;

    /**
     * 查询所有字典
     *
     * @return List<Dictionary>
     */
    @Override
    public List<com.trade.module.base.entity.Dictionary> findDictionaryAll() {
        List<SearchFilter> filters = SearchFilter.parse(null);//解析查询条件,自动田间数据状态过滤
        return dictionaryRepository.findAll(DynamicSpecifications.bySearchFilter(filters, Dictionary.class));
    }

    /**
     * Method description：根据条件分页查询数据字典
     *
     * @param pageNum            当前页码，为null或者为0将查询所有有效数据
     * @param pageSize           每页查询条数，默认为10
     * @param sortJsonArray      排序的json数组，格式为[{property:"排序字段名",direction:"ASC/DESC"}]，null、空字符串及[]将被认为是不进行排序
     * @param conditionJsonArray 查询条件的json数组，格式为[{property:"字段名",option:"操作类型",value:"值",propertytype:"数据类型"}]
     *                           其中option的值有EQ(等于), IN(在值数组中), ISNULL(非空), LIKE(包含), GT(大于), LT(小于), GTE(大于等于),
     *                           LTE(小于等于), NE(不等于),LIKEIGNORE(包含，忽略大小写)
     *                           propertytype为DATETIME或DATE，DATETIME值格式为YYYY-MM-dd HH:mm:ss，DATE值格式为YYYY-MM-dd
     *                           <p/>
     *                           conditionJsonArray为null、空字符串及[]将被认为是不进行条件过滤
     * @return ResponsePaging
     */
    @Override
    public ResponsePaging<List<Dictionary>> findDictionaryPageByCondition(Integer pageNum, Integer pageSize, String sortJsonArray, String conditionJsonArray) {
        List<SearchFilter> filters = SearchFilter.parse(conditionJsonArray);//解析查询条件
        PageBeanFactory pageBeanFactory = PageBeanFactory.getInstance();//声明返回结果构建工厂
        //如果nextPage为null或者为0则查询所有数据，否则进行分页查询
        if ((null != pageNum) && (pageNum.intValue() >= 0)) {
            //获取分页查询信息，进行分页查询并返回结果
            Pageable pageable = WebUitl.buildPageRequest(pageNum.intValue(), pageSize, sortJsonArray);//声明分页
            Page<Dictionary> dictionaryPage = dictionaryRepository.findAll(DynamicSpecifications.bySearchFilter(filters,
                    Dictionary.class), pageable);
            List<DictionaryVo> dicVoList = new ArrayList<>();
            //判断查询结果是否为空。
            if ((dictionaryPage != null) && (dictionaryPage.getContent() != null)
                    && (dictionaryPage.getContent().size() > 0)) {
                List<Dictionary> dictList = dictionaryPage.getContent();
                dicVoList = poToVo(dictList);
            }
            return pageBeanFactory.getResponsePagingByList(dictionaryPage, dicVoList);
        } else {
            //获取排序信息，如果无排序信息则直接根据条件查询，如果有排序信息则根据条件排序查询
            Sort sort = WebUitl.buildSort(sortJsonArray);
            List<Dictionary> dictionaryList = null;
            if (null == sort) {
                dictionaryList = dictionaryRepository.findAll(DynamicSpecifications.bySearchFilter(filters, Dictionary.class));
            } else {
                dictionaryList = dictionaryRepository.findAll(DynamicSpecifications.bySearchFilter(filters, Dictionary.class), sort);
            }
            List<DictionaryVo> dicVoList = poToVo(dictionaryList);
            // 返回结果
            return pageBeanFactory.getResponsePagingByList(dicVoList);
        }
    }

    /**
     * 根据ID删除数据字典
     *
     * @param id     字典id
     * @param userId 当前登录用户id
     */
    @Override
    public int deleteById(String id, String userId) {
        int countOperate = 0;
        if (XaUtil.isEmpty(userId)) {
            return countOperate;
        }
        //查询报表，如果存在，则设置为删除状态
        Dictionary dictionary = dictionaryRepository.findOne(id);
        if (null != dictionary) {
            dictionary.setDataFlag(Constants.DATA_FLAG_DELETE);
            dictionary.setModifyId(userId);
            dictionaryRepository.save(dictionary);
            //同步到内存
            DictionaryUtil.getInstance().initDicToMemory();
            countOperate = 1;
        } else {
            log.warn("删除的字典不存在！");
        }
        return countOperate;
    }

    /**
     * 根据ID查询数据字典
     *
     * @param id 字典id
     */
    @Override
    public DictionaryVo getById(String id) {
        DictionaryVo dicVo = new DictionaryVo();
        Dictionary dictionary = dictionaryRepository.findOne(id);
        if (null != dictionary) {
            try {
                BeanUtil.copyAllProperties(dictionary, dicVo);
            } catch (Exception e) {
                log.error("拷贝对象出错，对象为：" + dictionary);
                e.printStackTrace();
            }
            List<Dictionary> subDicList = dictionaryRepository.findByDicParentId(dictionary.getId());
            dicVo.setSubDicList(subDicList);
            User user = userRepository.findOne(dictionary.getCreaterId());
            dicVo.setUserAccount(user != null ? user.getAccount() : "");
        }
        return dicVo;
    }

    /**
     * 新增数据字典
     *
     * @param dictionaryVo 字典vo对象
     * @return Dictionary
     */
    @Override
    public Dictionary save(DictionaryVo dictionaryVo) {
        Dictionary dict = new Dictionary();
        String dicParentId = null;
        Dictionary dictionaryPo = null;
        try {
            BeanUtil.copyAllProperties(dictionaryVo, dict);
            dict.setDicFlag(Constants.DATA_FLAG_OK);
            dict.setDicLevel(Constants.DIC_LEVEL_1);
            dict.setDicParentId(null);
            boolean res = existsDict(dict);
            if(!res){
                dictionaryPo = dictionaryRepository.save(dict);
            } else {
                log.error("该字典已经存在");
                return dictionaryPo;
            }
            if(dictionaryPo!=null){
                dicParentId = dictionaryPo.getId();
            }
        } catch (Exception e) {
            log.error("拷贝对象失败！对象为：" + dictionaryVo);
            e.printStackTrace();
        }
        List<Dictionary> subDicList = dictionaryVo.getSubDicList();
        if (null!=subDicList && subDicList.size()>0 && null!=dicParentId) {
            for(Dictionary dictionary:subDicList){
                dictionary.setDicParentId(dicParentId);
                dictionary.setDicLevel(Constants.DIC_LEVEL_2);
                dictionary.setCreaterId(dictionaryVo.getCreaterId());
                dictionary.setDicFlag(Constants.DATA_FLAG_OK);
                dictionaryRepository.save(dictionary);
            }
        }
        return dictionaryPo;
    }

    /**
     * 判断字典值是否已存在
     *
     * @param dictionary 字典对象
     * @return boolean
     */
    public boolean existsDict(Dictionary dictionary) {
        boolean result = false;
        List<SearchFilter> filters = SearchFilter.parse(null);
        SearchFilter flagFilter = filters.get(0);
        SearchFilter dicLevelFilter = new SearchFilter("dicLevel", SearchFilter.Operator.EQ, dictionary.getDicLevel());
        SearchFilter dicCodeFilter = new SearchFilter("dicCode", SearchFilter.Operator.EQ, dictionary.getDicCode());
        filters.add(dicLevelFilter);
        filters.add(dicCodeFilter);
        List<Dictionary> exists = dictionaryRepository.findAll(DynamicSpecifications.bySearchFilter(filters, Dictionary.class));
        if (null == exists || 0 == exists.size()) {
            flagFilter.value = Constants.DATA_FLAG_DELETE;
            exists = dictionaryRepository.findAll(DynamicSpecifications.bySearchFilter(filters, Dictionary.class));
            if (null != exists && exists.size() > 0) {
                log.warn("该字典已经存在！且为已删除状态" + dictionary);
                result = true;
            } else {
                result = false;
            }
        } else {
            log.warn("该字典已经存在！" + dictionary);
            result = true;
        }
        return result;
    }

    /**
     * po—>vo
     *
     * @param dicList 字典list
     * @return List<DictionaryVo> 字典voList
     */
    private List<DictionaryVo> poToVo(List<Dictionary> dicList) {
        List<DictionaryVo> dicVoList = new ArrayList<>();
        //存放更新人Id
        Set<String> ids = new HashSet<>();
        //获取查询结果的所有更新人ID，并查询出所有包含ID的user，封装id与用户名到Map中
        for (Dictionary dic : dicList) {
            if (XaUtil.isNotEmpty(dic.getModifyId())) {
                ids.add(dic.getModifyId());
            }
        }
        Iterable<User> usersIterable = userRepository.findAll(ids);

        Map<String, String> userNameMap = new HashMap<String, String>();
        if (usersIterable != null) {
            for (User user : usersIterable) {
                userNameMap.put(user.getId(), user.getAccount());
            }
        }
        //深度拷贝对象信息并存储
        for (Dictionary dictionary : dicList) {
            DictionaryVo dictionaryVo = new DictionaryVo();
            try {
                BeanUtil.copyAllProperties(dictionary, dictionaryVo);
            } catch (Exception e) {
                log.error("资源PO对象转VO对象错误，资源信息：" + JSONObject.fromObject(dictionary));
                e.printStackTrace();
            }
            dictionaryVo.setUserAccount(userNameMap.get(dictionary.getModifyId()));
            dicVoList.add(dictionaryVo);
        }
        return dicVoList;
    }
}
